<?php

namespace App\Service\Activity;

use App\Library\Rms\RmsUserApi;
use App\Models\Activity\ActivityActionModel;
use App\Models\Activity\ActivityModel;
use App\Models\Activity\ActivityShopJoinModel;
use App\Models\Cruise\CruiseOrderModel;
use App\Models\Cruise\CruiseOrderProcessV2Model;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\Shop\ShopModel;
use App\Service\BaseService;
use App\Service\Cruise\Mission\ActivityInputService;

class ActivityAuditService extends BaseService
{
    public static function detail(int $id, int $userId)
    {
        $query = ActivityShopJoinModel::withoutGlobalScope('isDel')
                                      ->with('activityRel', 'shopRel')
                                      ->find($id);
        if (!$query) {
            BaseService::throwErr("不存在的审核记录:{$id}");
        }

        if ($query->actionType == ActivityActionModel::ACTION_TYPE_1) {
            BaseService::throwErr("无需审核的记录:{$id}");
        }

        $activityRel = optional($query->activityRel);
        $shopRel     = optional($query->shopRel);

        $merchantUid = (int)OpenShopSignOrderModel::query()
                                                  ->where('shopCode', $shopRel->shopCode)
                                                  ->value('merchantUserId');

        // 提交时间
        $submitFirstTime = $query
            ->cruiseOrderProcessV2Rel
            ->where('cruiseOrderStatus', CruiseOrderModel::STATUS_NOT_SUBMIT)
            ->sortBy('id')
            ->first();
        $submitFirstTime = $submitFirstTime ? strtotime($submitFirstTime['createdAt'] ?? '') : 0;


        // 最后提交时间
        $submitLastTime = $query
            ->cruiseOrderProcessV2Rel
            ->where('cruiseOrderStatus', CruiseOrderModel::STATUS_NOT_SUBMIT)
            ->sortByDesc('id')
            ->first();
        $submitLastTime = $submitLastTime ? strtotime($submitLastTime['createdAt'] ?? '') : 0;

        // 最后审核时间
        $auditLast = $query
            ->cruiseOrderProcessV2Rel
            ->where('cruiseOrderStatus', CruiseOrderModel::STATUS_NOT_REVIEW)
            ->sortByDesc('id')
            ->first();

        // 用户信息
        $uids = [
            $auditLast->createdByUid ?? 0,
            $query->submitUseId,
            $merchantUid,
            (int)$shopRel->councilorId,
        ];

        foreach ($query->cruiseOrderProcessV2Rel as $item) {
            $uids[] = $item->createdByUid;
        }

        $users = (new RmsUserApi())->getUserInfoByIds(array_values(array_unique(array_filter($uids))),
            ['id', 'username', 'mobile'])['data'] ?? [];
        $users = array_column($users, null, 'id');

        $merchantUser = $users[$merchantUid] ?? [];
        $submitter    = $users[$query->submitUseId] ?? [];
        $auditter     = $users[$auditLast->createdByUid ?? 0] ?? [];

        // 日志
        $logs = $query
            ->cruiseOrderProcessV2Rel
            ->map(function ($item) use ($users) {

                if ($item->cruiseOrderStatus == CruiseOrderModel::STATUS_NOT_SUBMIT) {
                    $name = '提交表单';
                } elseif ($item->cruiseOrderStatus == CruiseOrderModel::STATUS_NOT_REVIEW) {

                    if ($item->type == CruiseOrderProcessV2Model::TYPE_REJECT) {
                        $name = '审核驳回';
                    } elseif ($item->type == CruiseOrderProcessV2Model::TYPE_AGREE) {
                        $name = '审核通过';
                    } else {
                        $name = '-';
                    }

                } else {
                    $name = '';
                }

                return [
                    'createdAt'         => $item->createdAt->timestamp,
                    'createdByUsername' => $users[$item->createdByUid]['username'] ?? '',
                    'name'              => $name,
                    'type'              => $item->type,
                    'detail'            => collect(json_decode($item->details, true) ?? [])
                        ->map(function ($value, $field) {
                            return [
                                'field' => $field,
                                'value' => $value,
                            ];
                        })->values(),
                ];
            })
            ->toArray();

        $data = [
            'base'      => [
                'shopName'      => ((string)$shopRel->shopCode) . ((string)$shopRel->name),
                'addressPrefix' => (string)$shopRel->addressPrefix,
                'address'       => (string)$shopRel->address,
                'supervisorUid' => (int)$shopRel->councilorId,
                'supervisor'    => $users[(int)$shopRel->councilorId]['username'] ?? '',
                'merchantName'  => ($merchantUser['username'] ?? '') . "-" . ($merchantUser['mobile'] ?? ''),
            ],
            'activity'  => [
                'name'       => (string)$activityRel->name,
                'actionName' => (string)$activityRel->name,
            ],
            'submitter' => [
                'uid'       => $query->submitUseId,
                'mobile'    => $submitter['mobile'] ?? '',
                'name'      => $submitter['username'] ?? '',
                'createdAt' => $submitFirstTime,
                'updatedAt' => $submitLastTime,
            ],
            'audit'     => [
                'name'         => $auditter['username'] ?? '',
                'status'       => $query->status,
                'statusText'   => ActivityShopJoinModel::STATUS_TEXT[$query->status] ?? '',
                'createdAt'    => $auditLast ? strtotime($auditLast['createdAt'] ?? '') : null,
                'rejectReason' => $auditLast ? ($auditLast['content'] ?? '') : '',
            ],
            'inputs'    => (new ActivityInputService((int)$query->orderNo, $userId))->getInputObjectFill(),
            'logs'      => $logs,
        ];

        if ($query->isDeleted == 1) {
            $data['audit']['status'] = 4;
            $data['audit']['statusText'] = '已删除';
        }

        return $data;
    }

    public static function lists(array $data)
    {
        $paginator = ActivityShopJoinModel
            ::withoutGlobalScope('isDel')
            ->join((new CruiseOrderModel())->getTable() . ' as cruise', 'cruise.id', '=', 'activity_shop_join.orderNo')
            ->with('activityRel', 'cruiseOrderProcessV2Rel')
            ->where('actionType', ActivityActionModel::ACTION_TYPE_2)
            ->when($data['activityName'], function ($query) use ($data) {

                $activityIds = ActivityModel::query()
                                            ->where('name', 'like', "%{$data['activityName']}%")
                                            ->pluck('id')
                                            ->toArray();

                $query->whereIn('activityId', $activityIds);
            })
            ->when($data['activityType'], function ($query) use ($data) {

                $activityIds = ActivityModel::query()
                                            ->where('activityType', $data['activityType'])
                                            ->pluck('id')
                                            ->toArray();

                $query->whereIn('activityId', $activityIds);
            })
            ->when($data['activityStartDateTime'], function ($query) use ($data) {

                $activityIds = ActivityModel::query()
                                            ->where('startTime', '>=', strtotime($data['activityStartDateTime']))
                                            ->pluck('id')
                                            ->toArray();

                $query->whereIn('activityId', $activityIds);
            })
            ->when($data['activityEndDateTime'], function ($query) use ($data) {

                $activityIds = ActivityModel::query()
                                            ->where('startTime', '<=', strtotime($data['activityEndDateTime']) + 86399)
                                            ->pluck('id')
                                            ->toArray();

                $query->whereIn('activityId', $activityIds);
            })
            ->when($data['shopIds'], function ($query) use ($data) {
                $query->whereIn('activity_shop_join.shopId', explode(',', $data['shopIds']));
            })
            ->when($data['shopCodes'], function ($query) use ($data) {

                $shopIds = ShopModel::query()
                                    ->whereIn('shopCode', explode(',', $data['shopCodes']))
                                    ->pluck('id')
                                    ->toArray();

                $query->whereIn('activity_shop_join.shopId', $shopIds);
            })
            ->when($data['actionName'], function ($query) use ($data) {

                $ids = ActivityActionModel::query()
                                          ->where('name', 'like', "%{$data['actionName']}%")
                                          ->pluck('id')
                                          ->toArray();

                $query->whereIn('activityActionId', $ids);
            })
            ->when($data['submitUid'], function ($query) use ($data) {
                $query->where('submitUseId', $data['submitUid']);
            })
            ->when($data['submitMobile'], function ($query) use ($data) {

                $uid = (new RmsUserApi())->getUserInfoByMobiles([$data['submitMobile']])['data'][0]['id'] ?? 0;

                $query->where('submitUseId', $uid);
            })
            ->when($data['auditStatus'] !== null, function ($query) use ($data) {

                if ($data['auditStatus'] == ActivityShopJoinModel::STATUS_99) {
                    $query->where('activity_shop_join.isDeleted', 1);
                } else {
                    $query->where('activity_shop_join.status', $data['auditStatus'])
                          ->where('activity_shop_join.isDeleted', 0);
                }
            })
            ->when($data['auditUid'], function ($query) use ($data) {
                $query->where('approveUseId', $data['auditUid']);
            })
            ->when($data['remark'], function ($query) use ($data) {
                $query->where('remark', $data['remark']);
            })
            ->select("activity_shop_join.*", 'cruise.status as cruiseStatus', 'cruise.createdByUid as cruiseUid')
            ->orderByDesc('activity_shop_join.updatedAt')
            ->paginate($data['pageSize'], ['*'], 'pageNum', $data['pageNum']);

        $uids = [];

        $lists = collect($paginator->items())
            ->map(function (ActivityShopJoinModel $activityShopJoinModel) use (&$uids) {

                $activityRel = optional($activityShopJoinModel->activityRel);
                $shopRel     = optional($activityShopJoinModel->shopRel);
                $actionRel   = optional($activityShopJoinModel->activityActionRel);

                // 驳回原因
                $rejectReason = '';

                // 最后一条审批记录
                if ($activityShopJoinModel->cruiseStatus == CruiseOrderModel::STATUS_NOT_MODIFY) {
                    $rejectReason = $activityShopJoinModel
                        ->cruiseOrderProcessV2Rel
                        ->where('cruiseOrderStatus', CruiseOrderModel::STATUS_NOT_REVIEW)
                        ->where('type', CruiseOrderProcessV2Model::TYPE_REJECT)
                        ->sortByDesc('id')
                        ->first()['content'] ?? '';
                }

                // 提交人
                $uids[] = $activityShopJoinModel->submitUseId;

                // 督导
                $uids[] = (int)$shopRel->councilorId;

                return [
                    'id'        => $activityShopJoinModel->id,
                    'activity'  => [
                        'name'       => (string)$activityRel->name,
                        'typeText'   => ActivityModel::ACTIVITY_TYPE_TEXT[(int)$activityRel->activityType] ?? '',
                        'status'     => (int)$activityRel->status,
                        'statusText' => ActivityModel::STATUS_TEXT[(int)$activityRel->status] ?? '',
                        'startTime'  => $activityRel->startTime ? date('Y-m-d', (int)$activityRel->startTime) : '',
                        'endTime'    => $activityRel->endTime ? date('Y-m-d', (int)$activityRel->endTime) : '',
                        'actionName' => (string)$actionRel->name,
                        'remark'     => (string)$activityRel->remark,
                    ],
                    'audit' => [
                        'status'       => $auditStatus = ($activityShopJoinModel->isDeleted ? ActivityShopJoinModel::STATUS_99 : $activityShopJoinModel->status),
                        'statusText'   => ActivityShopJoinModel::STATUS_TEXT[$auditStatus] ?? '',
                        'rejectReason' => $rejectReason,
                    ],
                    'submitter' => [
                        'uid'    => $activityShopJoinModel->submitUseId,
                        'mobile' => '',
                        'name'   => '',
                    ],
                    'shop'      => [
                        'shopName'      => ((string)$shopRel->shopCode) . ((string)$shopRel->name),
                        'addressPrefix' => (string)$shopRel->addressPrefix,
                        'supervisorUid' => (int)$shopRel->councilorId,
                        'supervisor'    => '',
                    ],
                ];
            });

        // 批量获取用户信息
        $users = (new RmsUserApi())->getUserInfoByIds(array_values(array_unique(array_filter($uids))),
            ['id', 'username', 'mobile'])['data'] ?? [];
        $users = array_column($users, null, 'id');

        // 更新用户信息
        $lists = $lists->map(function ($item) use ($users) {
            $item['submitter']['mobile'] = $users[$item['submitter']['uid']]['mobile'] ?? '';
            $item['submitter']['name']   = $users[$item['submitter']['uid']]['username'] ?? '';
            $item['shop']['supervisor']  = $users[$item['shop']['supervisorUid']]['username'] ?? '';

            return $item;
        });

        return [
            'pageNum'   => $paginator->currentPage(),
            'pageSize'  => $paginator->perPage(),
            'pageCount' => ceil($paginator->total() / $paginator->perPage()),
            'count'     => $paginator->total(),
            'lists'     => $lists,
        ];
    }
}
